//
// crapgame.cpp
//
#include "lib.h"

#include "crapgame.h"
#include "crapconn.h"
#include "crapsave.h"
#include "crround.h"
#include "crbet.h"
#include "getrand.h"
#include "tbllim.h"
#include "log.h"
#include "opts.h"

#include <memory.h>

#include "badpacketmsgs.h"

#include "CrapsSQL.h"

CrapsGame::CrapsGame(CrapsConnection* conn)
{
	m_conn = conn;

	m_point = 0;
	m_diceTotal = 0;

	m_tableLimits = ((CrapsSQL *) conn->getGameDBInterface())->getTableLimits();

	memset(m_betAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);
	memset(m_bonusPayAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);

	m_round = new CrapsRound;
	m_current = new CrapsRound;

	// create the bets
	m_round->addBet(new PassBet(CrapsBet::Pass) );
	m_round->addBet(new DontPassBet(CrapsBet::DontPass) );
	m_round->addBet(new PassOddsBet(CrapsBet::PassOdds, m_round->getBet(CrapsBet::Pass), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontPassOddsBet(CrapsBet::DontPassOdds, m_round->getBet(CrapsBet::DontPass), &(m_tableLimits->m_betOdds) ));

	m_round->addBet(new FieldBet(CrapsBet::Field) );
	m_round->addBet(new BigBet(CrapsBet::Big6) );
	m_round->addBet(new BigBet(CrapsBet::Big8) );

	m_round->addBet(new ComeBet(CrapsBet::Come) );
	m_round->addBet(new DontComeBet(CrapsBet::DontCome) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come4) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come4Odds, m_round->getBet(CrapsBet::Come4), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome4) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome4Odds, m_round->getBet(CrapsBet::DontCome4), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy4) );
	m_round->addBet(new PlaceBet(CrapsBet::Place4) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place4Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay4) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come5) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come5Odds, m_round->getBet(CrapsBet::Come5), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome5) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome5Odds, m_round->getBet(CrapsBet::DontCome5), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy5) );
	m_round->addBet(new PlaceBet(CrapsBet::Place5) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place5Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay5) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come6) );
	m_round->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come6Odds, m_round->getBet(CrapsBet::Come6), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome6) );
	m_round->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome6Odds, m_round->getBet(CrapsBet::DontCome6), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy6) );
	m_round->addBet(new PlaceBet(CrapsBet::Place6) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place6Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay6) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come8) );
	m_round->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come8Odds, m_round->getBet(CrapsBet::Come8), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome8) );
	m_round->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome8Odds, m_round->getBet(CrapsBet::DontCome8), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy8) );
	m_round->addBet(new PlaceBet(CrapsBet::Place8) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place8Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay8) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come9) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come9Odds, m_round->getBet(CrapsBet::Come9), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome9) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome9Odds, m_round->getBet(CrapsBet::DontCome9), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy9) );
	m_round->addBet(new PlaceBet(CrapsBet::Place9) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place9Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay9) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come10) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come10Odds, m_round->getBet(CrapsBet::Come10), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome10) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome10Odds, m_round->getBet(CrapsBet::DontCome10), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy10) );
	m_round->addBet(new PlaceBet(CrapsBet::Place10) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place10Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay10) );

	m_round->addBet(new HardBet(CrapsBet::Hard4) );
	m_round->addBet(new HardBet(CrapsBet::Hard6) );
	m_round->addBet(new HardBet(CrapsBet::Hard8) );
	m_round->addBet(new HardBet(CrapsBet::Hard10) );

	m_round->addBet(new OneTimeBet(CrapsBet::Seven) );
	m_round->addBet(new OneTimeBet(CrapsBet::AnyCraps) );
	m_round->addBet(new OneTimeBet(CrapsBet::Craps3) );
	m_round->addBet(new OneTimeBet(CrapsBet::SnakeEyes) );
	m_round->addBet(new OneTimeBet(CrapsBet::Eleven) );
	m_round->addBet(new OneTimeBet(CrapsBet::BoxCars) );
	m_round->addBet(new OneTimeBet(CrapsBet::YoEleven) );
	m_round->addBet(new OneTimeBet(CrapsBet::CircleAnyCraps) );


	m_current->addBet(new PassBet(CrapsBet::Pass) );
	m_current->addBet(new DontPassBet(CrapsBet::DontPass) );
	m_current->addBet(new PassOddsBet(CrapsBet::PassOdds, m_current->getBet(CrapsBet::Pass), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontPassOddsBet(CrapsBet::DontPassOdds, m_current->getBet(CrapsBet::DontPass), &(m_tableLimits->m_betOdds) ));

	m_current->addBet(new FieldBet(CrapsBet::Field) );
	m_current->addBet(new BigBet(CrapsBet::Big6) );
	m_current->addBet(new BigBet(CrapsBet::Big8) );

	m_current->addBet(new ComeBet(CrapsBet::Come) );
	m_current->addBet(new DontComeBet(CrapsBet::DontCome) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come4) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come4Odds, m_current->getBet(CrapsBet::Come4), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome4) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome4Odds, m_current->getBet(CrapsBet::DontCome4), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy4) );
	m_current->addBet(new PlaceBet(CrapsBet::Place4) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place4Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay4) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come5) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come5Odds, m_current->getBet(CrapsBet::Come5), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome5) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome5Odds, m_current->getBet(CrapsBet::DontCome5), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy5) );
	m_current->addBet(new PlaceBet(CrapsBet::Place5) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place5Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay5) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come6) );
	m_current->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come6Odds, m_current->getBet(CrapsBet::Come6), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome6) );
	m_current->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome6Odds, m_current->getBet(CrapsBet::DontCome6), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy6) );
	m_current->addBet(new PlaceBet(CrapsBet::Place6) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place6Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay6) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come8) );
	m_current->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come8Odds, m_current->getBet(CrapsBet::Come8), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome8) );
	m_current->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome8Odds, m_current->getBet(CrapsBet::DontCome8), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy8) );
	m_current->addBet(new PlaceBet(CrapsBet::Place8) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place8Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay8) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come9) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come9Odds, m_current->getBet(CrapsBet::Come9), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome9) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome9Odds, m_current->getBet(CrapsBet::DontCome9), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy9) );
	m_current->addBet(new PlaceBet(CrapsBet::Place9) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place9Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay9) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come10) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come10Odds, m_current->getBet(CrapsBet::Come10), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome10) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome10Odds, m_current->getBet(CrapsBet::DontCome10), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy10) );
	m_current->addBet(new PlaceBet(CrapsBet::Place10) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place10Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay10) );

	m_current->addBet(new HardBet(CrapsBet::Hard4) );
	m_current->addBet(new HardBet(CrapsBet::Hard6) );
	m_current->addBet(new HardBet(CrapsBet::Hard8) );
	m_current->addBet(new HardBet(CrapsBet::Hard10) );

	m_current->addBet(new OneTimeBet(CrapsBet::Seven) );
	m_current->addBet(new OneTimeBet(CrapsBet::AnyCraps) );
	m_current->addBet(new OneTimeBet(CrapsBet::Craps3) );
	m_current->addBet(new OneTimeBet(CrapsBet::SnakeEyes) );
	m_current->addBet(new OneTimeBet(CrapsBet::Eleven) );
	m_current->addBet(new OneTimeBet(CrapsBet::BoxCars) );
	m_current->addBet(new OneTimeBet(CrapsBet::YoEleven) );
	m_current->addBet(new OneTimeBet(CrapsBet::CircleAnyCraps) );
}

CrapsGame::CrapsGame(CrapsConnection *conn, CrapsSavedGame *saved)
{
	m_conn = conn;

	// initialize (restored later below)
	m_point		= 0;
	m_die1		= 0;
	m_die2		= 0;
	m_diceTotal = 0;
	memset(m_betAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);
	memset(m_bonusPayAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);

	m_tableLimits = ((CrapsSQL *) conn->getGameDBInterface())->getTableLimits();

	m_round = new CrapsRound;
	m_current = new CrapsRound;

	// create the bets
	m_round->addBet(new PassBet(CrapsBet::Pass) );
	m_round->addBet(new DontPassBet(CrapsBet::DontPass) );
	m_round->addBet(new PassOddsBet(CrapsBet::PassOdds, m_round->getBet(CrapsBet::Pass), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontPassOddsBet(CrapsBet::DontPassOdds, m_round->getBet(CrapsBet::DontPass), &(m_tableLimits->m_betOdds) ));

	m_round->addBet(new FieldBet(CrapsBet::Field) );
	m_round->addBet(new BigBet(CrapsBet::Big6) );
	m_round->addBet(new BigBet(CrapsBet::Big8) );

	m_round->addBet(new ComeBet(CrapsBet::Come) );
	m_round->addBet(new DontComeBet(CrapsBet::DontCome) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come4) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come4Odds, m_round->getBet(CrapsBet::Come4), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome4) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome4Odds, m_round->getBet(CrapsBet::DontCome4), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy4) );
	m_round->addBet(new PlaceBet(CrapsBet::Place4) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place4Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay4) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come5) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come5Odds, m_round->getBet(CrapsBet::Come5), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome5) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome5Odds, m_round->getBet(CrapsBet::DontCome5), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy5) );
	m_round->addBet(new PlaceBet(CrapsBet::Place5) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place5Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay5) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come6) );
	m_round->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come6Odds, m_round->getBet(CrapsBet::Come6), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome6) );
	m_round->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome6Odds, m_round->getBet(CrapsBet::DontCome6), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy6) );
	m_round->addBet(new PlaceBet(CrapsBet::Place6) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place6Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay6) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come8) );
	m_round->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come8Odds, m_round->getBet(CrapsBet::Come8), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome8) );
	m_round->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome8Odds, m_round->getBet(CrapsBet::DontCome8), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy8) );
	m_round->addBet(new PlaceBet(CrapsBet::Place8) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place8Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay8) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come9) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come9Odds, m_round->getBet(CrapsBet::Come9), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome9) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome9Odds, m_round->getBet(CrapsBet::DontCome9), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy9) );
	m_round->addBet(new PlaceBet(CrapsBet::Place9) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place9Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay9) );

	m_round->addBet(new ComeSpecificBet(CrapsBet::Come10) );
	m_round->addBet(new ComeOddsBet(CrapsBet::Come10Odds, m_round->getBet(CrapsBet::Come10), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new DontComeSpecificBet(CrapsBet::DontCome10) );
	m_round->addBet(new DontComeOddsBet(CrapsBet::DontCome10Odds, m_round->getBet(CrapsBet::DontCome10), &(m_tableLimits->m_betOdds) ));
	m_round->addBet(new BuyBet(CrapsBet::Buy10) );
	m_round->addBet(new PlaceBet(CrapsBet::Place10) );
	m_round->addBet(new PlaceLoseBet(CrapsBet::Place10Lose) );
	m_round->addBet(new LayBet(CrapsBet::Lay10) );

	m_round->addBet(new HardBet(CrapsBet::Hard4) );
	m_round->addBet(new HardBet(CrapsBet::Hard6) );
	m_round->addBet(new HardBet(CrapsBet::Hard8) );
	m_round->addBet(new HardBet(CrapsBet::Hard10) );

	m_round->addBet(new OneTimeBet(CrapsBet::Seven) );
	m_round->addBet(new OneTimeBet(CrapsBet::AnyCraps) );
	m_round->addBet(new OneTimeBet(CrapsBet::Craps3) );
	m_round->addBet(new OneTimeBet(CrapsBet::SnakeEyes) );
	m_round->addBet(new OneTimeBet(CrapsBet::Eleven) );
	m_round->addBet(new OneTimeBet(CrapsBet::BoxCars) );
	m_round->addBet(new OneTimeBet(CrapsBet::YoEleven) );
	m_round->addBet(new OneTimeBet(CrapsBet::CircleAnyCraps) );


	m_current->addBet(new PassBet(CrapsBet::Pass) );
	m_current->addBet(new DontPassBet(CrapsBet::DontPass) );
	m_current->addBet(new PassOddsBet(CrapsBet::PassOdds, m_current->getBet(CrapsBet::Pass), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontPassOddsBet(CrapsBet::DontPassOdds, m_current->getBet(CrapsBet::DontPass), &(m_tableLimits->m_betOdds) ));

	m_current->addBet(new FieldBet(CrapsBet::Field) );
	m_current->addBet(new BigBet(CrapsBet::Big6) );
	m_current->addBet(new BigBet(CrapsBet::Big8) );

	m_current->addBet(new ComeBet(CrapsBet::Come) );
	m_current->addBet(new DontComeBet(CrapsBet::DontCome) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come4) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come4Odds, m_current->getBet(CrapsBet::Come4), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome4) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome4Odds, m_current->getBet(CrapsBet::DontCome4), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy4) );
	m_current->addBet(new PlaceBet(CrapsBet::Place4) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place4Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay4) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come5) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come5Odds, m_current->getBet(CrapsBet::Come5), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome5) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome5Odds, m_current->getBet(CrapsBet::DontCome5), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy5) );
	m_current->addBet(new PlaceBet(CrapsBet::Place5) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place5Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay5) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come6) );
	m_current->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come6Odds, m_current->getBet(CrapsBet::Come6), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome6) );
	m_current->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome6Odds, m_current->getBet(CrapsBet::DontCome6), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy6) );
	m_current->addBet(new PlaceBet(CrapsBet::Place6) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place6Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay6) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come8) );
	m_current->addBet(new ComeFullDoubleOddsBet(CrapsBet::Come8Odds, m_current->getBet(CrapsBet::Come8), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome8) );
	m_current->addBet(new DontComeFullDoubleOddsBet(CrapsBet::DontCome8Odds, m_current->getBet(CrapsBet::DontCome8), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy8) );
	m_current->addBet(new PlaceBet(CrapsBet::Place8) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place8Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay8) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come9) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come9Odds, m_current->getBet(CrapsBet::Come9), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome9) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome9Odds, m_current->getBet(CrapsBet::DontCome9), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy9) );
	m_current->addBet(new PlaceBet(CrapsBet::Place9) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place9Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay9) );

	m_current->addBet(new ComeSpecificBet(CrapsBet::Come10) );
	m_current->addBet(new ComeOddsBet(CrapsBet::Come10Odds, m_current->getBet(CrapsBet::Come10), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new DontComeSpecificBet(CrapsBet::DontCome10) );
	m_current->addBet(new DontComeOddsBet(CrapsBet::DontCome10Odds, m_current->getBet(CrapsBet::DontCome10), &(m_tableLimits->m_betOdds) ));
	m_current->addBet(new BuyBet(CrapsBet::Buy10) );
	m_current->addBet(new PlaceBet(CrapsBet::Place10) );
	m_current->addBet(new PlaceLoseBet(CrapsBet::Place10Lose) );
	m_current->addBet(new LayBet(CrapsBet::Lay10) );

	m_current->addBet(new HardBet(CrapsBet::Hard4) );
	m_current->addBet(new HardBet(CrapsBet::Hard6) );
	m_current->addBet(new HardBet(CrapsBet::Hard8) );
	m_current->addBet(new HardBet(CrapsBet::Hard10) );

	m_current->addBet(new OneTimeBet(CrapsBet::Seven) );
	m_current->addBet(new OneTimeBet(CrapsBet::AnyCraps) );
	m_current->addBet(new OneTimeBet(CrapsBet::Craps3) );
	m_current->addBet(new OneTimeBet(CrapsBet::SnakeEyes) );
	m_current->addBet(new OneTimeBet(CrapsBet::Eleven) );
	m_current->addBet(new OneTimeBet(CrapsBet::BoxCars) );
	m_current->addBet(new OneTimeBet(CrapsBet::YoEleven) );
	m_current->addBet(new OneTimeBet(CrapsBet::CircleAnyCraps) );

	// everything else is restored in restore()
	restore(saved);
}

CrapsGame::~CrapsGame()
{
	delete m_round;
	m_round = (CrapsRound *)0;

	delete m_current;
	m_current = (CrapsRound *)0;

	m_conn		= (CrapsConnection *)0;
	m_point		= 0;
	m_die1		= 0;
	m_die2		= 0;
	m_diceTotal = 0;

	memset(m_betAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);
	memset(m_bonusPayAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);

}

void
CrapsGame::setPoint(uint8 total)
{
	if (m_point > 0)		//  point established
	{
		if (total == m_point)
			m_point = 0;		// point was made
		else if (total == 7)
			m_point = 0;		// point was mot made
	}
	else				// no point established yet
	{
		if (total > 3 && total < 11 && total != 7)
			m_point = total;
	}
}

void
CrapsGame::setDice(uint8 die1, uint8 die2)
{
	m_die1 = die1;
	m_die2 = die2;
	m_diceTotal = die1 + die2;
}


//
// returns:
//	true	- no errors
//	false	- trackRoll() sql problem
//
bool8
CrapsGame::roll(CrapsRound *round, int32 *balance, int32 *compBalance, int32 *bonusBalance)
{
	int32 totalWinningBets = 0;
	int32 payout = 0;
	int32 bonusPayout = 0;
	int32 continueBets = 0;
	int32 continueBonusBets = 0;
	int32 totalbet = 0;
	uint8 numBets = 0;

	totalbet = round->totalBet();
	numBets = round->numBets();

	uint8 die1, die2;

	// CSN-5666: Force outcomes in Craps (DEBUG MODE)
	if(ServerOpts::bAllowTesting && ServerOpts::IsDebugCasinoName() && m_conn->isForcedRoll())
	{
		/*
		int32 iIndexDice1 = (m_iForcedRollRound*2) % m_iForcedRollCount;
		int32 iIndexDice2 = (m_iForcedRollRound*2+1) % m_iForcedRollCount;
		die1 = m_iForcedRollValues[iIndexDice1];
		die2 = m_iForcedRollValues[iIndexDice2];
		m_iForcedRollRound++;	
		*/
		die1 = m_conn->getForcedRoll();
		die2 = m_conn->getForcedRoll();
	}
	else
	{
		die1 = (uint8)(getrand() % 6 + 1);
		die2 = (uint8)(getrand() % 6 + 1);
	}

	DEBUGMSG(("rolled %d %d", die1, die2));

	setDice(die1, die2);

	int32 *updatedBetAmounts = ProcessBets(round, &continueBets, &continueBonusBets);

	setPoint(die1 + die2);
	uint8 point = getPoint();

	totalWinningBets = calcTotalWinningBets();
	payout = calcPayout();
	bonusPayout = calcBonusPayout();

	// balance is adjusted within the stored procedure
	CrapsSQL *pSQL = (CrapsSQL *) m_conn->getGameDBInterface();
	if (pSQL->trackRoll(point, die1, die2,
		round, m_current,
		updatedBetAmounts, m_bonusPayAmounts,
		totalWinningBets, continueBets, continueBonusBets,
		payout, bonusPayout,
		balance, compBalance, bonusBalance))
	{
		m_conn->msgStart();

		m_conn->msgAdd((uint8)'R');
		m_conn->msgAdd(*balance);
		m_conn->msgAdd(payout);
		m_conn->msgAdd(totalWinningBets);

		m_conn->msgAdd(numBets);

		for (int32 i=0; i<numBets; i++)
		{
			m_conn->msgAdd(updatedBetAmounts[i]);
		}

		m_conn->msgAdd(point);
		m_conn->msgAdd(die2);
		m_conn->msgAdd(die1);

		m_conn->msgEnd();

	}
	else
		return false;


	return true;

}

void
CrapsGame::save()
{
	returnRemovableBets();
}

void
CrapsGame::returnRemovableBets()
{
	for (int32 i=0; i<CrapsBet::NUMBETS; i++)
	{
		CrapsBet *bet = m_current->getBet((uint8)i);
		int32 amount = bet->getAmount();

		// give back any bets that can be removed
		if ( amount && bet->canRemove(m_point) )			
		{
			// CGC: DontPass. Only removed if point is not established
			if (bet->getBetID() != CrapsBet::DontPass || m_point == 0)
			{
				ASSERT(amount > 0);

				// 'reset' the bet in the database
				CrapsSQL *pSQL = (CrapsSQL *) m_conn->getGameDBInterface();
				if (pSQL->trackScrubBet(bet->getBetID()))
				{
					bet->setAmount(0);
					bet->setBonusAmount(0);
					m_betAmounts[(uint8)i] = CrapsBet::LOST;
				}
			}
		}
	}
}

void
CrapsGame::restore(CrapsSavedGame *saved)
{

	for (int32 i=0; i<CrapsBet::NUMBETS; i++)
	{
		m_round->getBet((uint8)i)->setAmount( saved->bets.round[i] );
		m_current->getBet((uint8)i)->setAmount( saved->bets.current[i] );

		m_round->getBet((uint8)i)->setBonusAmount( saved->bets.bonusRound[i] );
		m_current->getBet((uint8)i)->setBonusAmount( saved->bets.bonusCurrent[i] );

		m_betAmounts[i] = saved->bets.state[i];
	}

	m_point						= saved->point;
	m_die1						= saved->die1;
	m_die2						= saved->die2;
	m_diceTotal					= m_die1 + m_die2;

	returnRemovableBets();
}


void
CrapsGame::send(bool8 bSaved)
{
	// kharmon.  06-19-06.  #3077.  Sic Bo implementation.
	// This "send" method now gets called everytime a player connects, 
	// and we send the table limit information here, and then if
	// there's a saved game, we send that info too.
	CrapsSQL *pSQL = (CrapsSQL *) m_conn->getGameDBInterface();
	CTableLimits *tableLimits = pSQL->getTableLimits();

	m_conn->msgAdd(tableLimits->m_minPassSet);
	m_conn->msgAdd(tableLimits->m_maxPassSet);
	m_conn->msgAdd(tableLimits->m_minOddsSet);
	m_conn->msgAdd(tableLimits->m_maxOddsSet);
	m_conn->msgAdd(tableLimits->m_minPlaceSet);
	m_conn->msgAdd(tableLimits->m_maxPlaceSet);
	m_conn->msgAdd(tableLimits->m_minHardPropsSet);
	m_conn->msgAdd(tableLimits->m_maxHardPropsSet);
	m_conn->msgAdd(tableLimits->m_minFieldBigSet);
	m_conn->msgAdd(tableLimits->m_maxFieldBigSet);
	m_conn->msgAdd(tableLimits->m_minTable);
	m_conn->msgAdd(tableLimits->m_maxTable);
	m_conn->msgAdd(tableLimits->m_betOdds);
	m_conn->msgAdd(tableLimits->m_field12Odds);

	m_conn->msgAdd((uint8)(bSaved ? 1 : 0));

	if(bSaved==false)
	{
		return;
	}

	// This message is contained within another message
	// (don't call msgStart()/msgEnd())

	// before we come here, restore() has been called which in turn,
	// calls returnRemovableBets(). So, at this point, the only bets
	// that are left are bets that will be grandfathered (non-removable ones).
	bool8 grandfather = true;


	m_conn->msgAdd(m_point);
	m_conn->msgAdd(m_die1);
	m_conn->msgAdd(m_die2);

	// send only the 'active' bets
	m_conn->msgAdd(m_current->numMoneyBets() );

	for (int32 i=0; i<CrapsBet::NUMBETS; i++)
	{
		CrapsBet *bet = m_current->getBet((uint8)i);
		if (bet)
		{
			int32 amount = bet->getAmount();

			if (amount > 0)
			{
				m_conn->msgAdd(bet->getBetID() );
				m_conn->msgAdd(amount);

				// mark bet as 'grandfathered'
				bet->grandfathered(true);
			}
		}
	}

	m_conn->msgAdd(grandfather);

}


int32
CrapsGame::calcPayout()
{
	// Payout includes original bet
	// (we give them back the original bet money too!)
	int32 i, payout = 0;

	for (i=0; i<CrapsBet::NUMBETS; i++)
	{
		CrapsBet *bet;

		bet = m_round->getBet((uint8)i);


		if (bet && (m_betAmounts[(uint8)i] > 0) )
			payout += m_betAmounts[(uint8)i] + bet->getAmount();

		// give back their bet on a Push
		if (bet && (m_betAmounts[(uint8)i] == CrapsBet::PUSH) )
			payout += bet->getAmount();
	}

	return payout;
}





int32
CrapsGame::calcBonusPayout()
{
	// Payout includes original bet
	// (we give them back the original bet money too!)
	int32 i, payout = 0;

	for (i=0; i<CrapsBet::NUMBETS; i++)
	{
		CrapsBet *bet;

		bet = m_round->getBet((uint8)i);


		if (bet && (m_bonusPayAmounts[(uint8)i] > 0) )
			payout += m_bonusPayAmounts[(uint8)i] + bet->getBonusAmount();

		// give back their bet on a Push
		if (bet && (m_betAmounts[(uint8)i] == CrapsBet::PUSH) )
			payout += bet->getBonusAmount();
	}

	return payout;
}


int32
CrapsGame::calcTotalWinningBets()
{
	int32 i, total;

	total = 0;

	for (i=0; i<CrapsBet::NUMBETS; i++)
	{
		if (m_betAmounts[(uint8)i] > 0)
			total += m_betAmounts[(uint8)i];
	}

	return total;
}

//
// round down to the nearest quarter (25 cents)
//
int32
CrapsGame::roundDownAmount(int32 amount)
{
	int32 whole = (amount / 100) * 100;
	int32 fraction = amount - whole;

	int32 multiplier = fraction / 25;

	return whole + multiplier * 25;
}



void
CrapsGame::CalcBonusWin (int32 netWin, int32 realBet, int32 bonusBet, int32 *realWin, int32 *bonusWin)
{
	// This should duplicate the prv_CalcBonusWin as implemented in the database
	//    It is impossible at this point to calculate the bonus allotment in the database for Craps
	if (realBet == 0)
	{
		*realWin = 0;
		*bonusWin = netWin;
	}
	else if (bonusBet == 0)
	{
		*realWin = netWin;
		*bonusWin = 0;
	}
	else
	{
		// Rounding/Truncation Rule:
		//	If there is an amount that goes INTo fractional cents, we will truncate the real amount and apply it to the bonus amount
		//  Calculate Percentage of Real To Bonus

		int32 intRealWin;
		double ratio;

		ratio = (double)realBet / ( (double)realBet + (double)bonusBet );

		intRealWin = (int32)(((double)netWin * (double)ratio * (double)100.0) / (double)100.0);

		*realWin = intRealWin;
		*bonusWin = netWin - intRealWin;
	}
}


void
CrapsGame::Winner(uint8 betID, int32 amount)
{
	int32 bonusBet = m_round->getBet(betID)->getBonusAmount();
	int32 realBet = m_round->getBet(betID)->getAmount() - bonusBet;
	int32 realPayout;

	// This holds the total payout (both real and bonus)
	m_betAmounts[betID] = roundDownAmount(amount);

	// Distribute payout among real and bonus balance
	CalcBonusWin (m_betAmounts[betID], realBet, bonusBet, &realPayout, &m_bonusPayAmounts[betID]);

	// Reset bet -- it is over
	m_current->getBet(betID)->setAmount(0);
	m_current->getBet(betID)->setBonusAmount(0);
	m_current->getBet(betID)->grandfathered(false);
}

void
CrapsGame::Loser(uint8 betID)
{
	m_betAmounts[betID] = CrapsBet::LOST;
	m_current->getBet(betID)->setAmount(0);
	m_current->getBet(betID)->setBonusAmount(0);
	m_current->getBet(betID)->grandfathered(false);
}

void
CrapsGame::Continue(uint8 betID)
{
	m_betAmounts[betID] = CrapsBet::CARRY;
}

void
CrapsGame::Push(uint8 betID)
{
	m_betAmounts[betID] = CrapsBet::PUSH;
	m_current->getBet(betID)->setAmount(0);
	m_current->getBet(betID)->setBonusAmount(0);
	m_current->getBet(betID)->grandfathered(false);
}

void
CrapsGame::MoveComeTo(uint8 betID, uint8 number)
{
	// indicate where the Come should be moved to
	m_betAmounts[CrapsBet::Come] = CrapsBet::MOVECOME - number;

	// set the Come # bet amount to be Come amount
	m_current->getBet(betID)->setAmount(m_round->getBet(CrapsBet::Come)->getAmount() );
	m_current->getBet(betID)->setBonusAmount(m_round->getBet(CrapsBet::Come)->getBonusAmount() );
	m_current->getBet(CrapsBet::Come)->setAmount(0);
	m_current->getBet(CrapsBet::Come)->setBonusAmount(0);
}

void
CrapsGame::MoveDontComeTo(uint8 betID, uint8 number)
{
	// indicate where the  Don't Come should be moved to
	m_betAmounts[CrapsBet::DontCome] = CrapsBet::MOVEDONTCOME - number;

	// set the Don't Come # bet amount to be Don't Come amount
	m_current->getBet(betID)->setAmount(m_round->getBet(CrapsBet::DontCome)->getAmount() );
	m_current->getBet(betID)->setBonusAmount(m_round->getBet(CrapsBet::DontCome)->getBonusAmount() );
	m_current->getBet(CrapsBet::DontCome)->setAmount(0);
	m_current->getBet(CrapsBet::DontCome)->setBonusAmount(0);
}


//
// This function must be called AFTER validateBets()
//
// in		- round
// in/out	- continueBets
// returns	- amounts (updated bet amounts)
//
int32*
CrapsGame::ProcessBets(CrapsRound *round, int32 *continueBets, int32 *continueBonusBets)
{

	// make a copy of the incoming round
	ASSERT(m_round->numBets() == round->numBets() );
	int32 numBets = round->numBets();

	// copy the bet data from the incoming round to the member round
	for (int32 i=0; i<numBets; i++)
	{
		*m_round->getBet((uint8)i) = *round->getBet((uint8)i); 
		// if a 'carried' bet was removed, give back that money
		if	(
			(m_round->getBet((uint8)i)->getAmount() == 0) &&
			(m_betAmounts[(uint8)i] == CrapsBet::CARRY)
			)
		{
			*continueBets += m_current->getBet((uint8)i)->getAmount();
			*continueBonusBets += m_current->getBet((uint8)i)->getBonusAmount();
            //RPF 20100518 RTG Already had discover this bug .. we need to reset the current round
			// CGC: discommenting because it produces a different bug
            //m_current->getBet((uint8)i)->setAmount(0);
            //m_current->getBet((uint8)i)->setBonusAmount(0);

		}
	}

	// reset the bet 'states'
	memset(m_betAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);
	memset(m_bonusPayAmounts, 0, sizeof(int32)*CrapsBet::NUMBETS);

	// update the bet amounts
	// (we are assuming all bets are valid)
	ProcessPassBets(continueBets, continueBonusBets);
	ProcessDontPassBets(continueBets, continueBonusBets);
	ProcessPassOddsBets(continueBets, continueBonusBets);
	ProcessDontPassOddsBets(continueBets, continueBonusBets);
	ProcessBigBets(CrapsBet::Big6, 6, continueBets, continueBonusBets);
	ProcessBigBets(CrapsBet::Big8, 8, continueBets, continueBonusBets);
	ProcessComeOddsBets(continueBets, continueBonusBets);
	ProcessDontComeOddsBets(continueBets, continueBonusBets);
	ProcessComeNumberBets(continueBets, continueBonusBets);
	ProcessDontComeNumberBets(continueBets, continueBonusBets);

	// come and don't come must be processed after the (dont)come number bets
	// because they involve moving bets -- we move after we 'payout'
	ProcessComeBets();
	ProcessDontComeBets();
	ProcessBuyBets(continueBets, continueBonusBets);
	ProcessPlaceBets(continueBets, continueBonusBets);
	ProcessPlaceLoseBets(continueBets, continueBonusBets);
	ProcessLayBets(continueBets, continueBonusBets);
	ProcessHardWays(continueBets, continueBonusBets);

	// one time bets
	ProcessFieldBet();
	ProcessOneShotBets();
	ProcessAnyCrapsBets();

	return m_betAmounts;
}

//
// verify all bets within round are valid
// returns -1 if all valid
// returns id of invalid bet otherwise
//
int32
CrapsGame::validateBets(CrapsRound *round)
{
	int32 betid = -1;
	uint8 numBets = round->numBets();

	int32 maxBet;


	for (int32 i=0; i<numBets; i++)
	{
		CrapsBet *bet = round->getBet((uint8)i);

		int32 amount	= bet->getAmount();
		maxBet			= m_tableLimits->getBetMax((uint8)i);

		//
		// check to see if bet was removed illegally
		//

		if (amount <= 0)
		{
			// if it's not supposed to be removed
			if (!bet->canRemove(getPoint() ) )
			{
				// check to see if the bet existed last round
				// (ie, was  a 'continuing' bet)
				if (m_current->getBet((uint8)i)->getAmount() > 0)
				{
					Log::msgError("validateBets failed - illegal to remove bet.");

					// then it is illegal to remove it now
					betid = i;
					break;
				}
			}
		}
		//
		// check to see if bet is within the limits
		//
		else
		{
			// if the current bet is not grandfathered,
			if ( !m_current->getBet((uint8)i)->isGrandfathered() )
			{
				// verify bet meets bet min
				if (amount < m_tableLimits->getBetMin((uint8)i) )
				{
					Log::msgError("validateBets failed - bet does not meet minimum.");

					betid = i;
					break;
				}
			}
			// otherwise, the bet is grandfathered and
			// we will not check that the bet meets the bet min
			// because we honour this bet at the previous limits
			// (the limits could have changed)
			else {}
			
			int32 limit = m_current->getBet((uint8)i)->getLimit(getPoint(), maxBet);

			// check to see if the bet exists
			int32 existedAmount = m_current->getBet((uint8)i)->getAmount();

			// trying to place a new bet that is not allowed to be made
			if ( (existedAmount <= 0) && ((limit == 0) || (amount > limit)) )
			{
				Log::msgError("validateBets failed - bet not allowed.");

				betid = i;
				break;
			}

			if (existedAmount > 0)
			{
				// if it exists and the amount can not be changed (increased),
				if (limit == 0)
				{
					// then these two amounts must be the same
					if (amount != existedAmount)
					{
						Log::msgError("validateBets failed - amount cannot be changed.");

						betid = i;
						break;
					}
				}
				else
				{
					// if the new amount is greater than the limit for this
					// bet on the server, then an illegal bet has been made.
					if (amount > limit)
					{
						Log::msgError("validateBets failed - bet exceeds maximum.");

						betid = i;
						break;
					}

				}
			}

		}
	}

	return betid;
}



void
CrapsGame::ProcessPassBets(int32 *continueBets, int32 *continueBonusBets)
{
	if (m_point == 0)
	{
		if (m_round->getBet(CrapsBet::Pass)->getAmount() > 0)
		{
			// pass line winner
			if (m_diceTotal == 7 || m_diceTotal == 11)
				Winner(CrapsBet::Pass, m_round->getBet(CrapsBet::Pass)->getAmount() );

			// pass line loser
			else if (m_diceTotal == 2 || m_diceTotal == 3 || m_diceTotal == 12)
				Loser(CrapsBet::Pass);

			else
			{
				if (m_current->getBet(CrapsBet::Pass)->getAmount() == 0)
				{
					*m_current->getBet(CrapsBet::Pass) = *m_round->getBet(CrapsBet::Pass);
				}

				Continue(CrapsBet::Pass);

			}
		}
		// clear any previous results still hanging around
		else
			Loser(CrapsBet::Pass);
	}
	// if we've come here, then the bet exists in the 'current game' --
	// it must have previously been made,
	else
	{
		if (m_current->getBet(CrapsBet::Pass)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(CrapsBet::Pass)->getAmount();
			*continueBonusBets += m_current->getBet(CrapsBet::Pass)->getBonusAmount();

			if (m_diceTotal == m_point)
				Winner(CrapsBet::Pass, m_round->getBet(CrapsBet::Pass)->getAmount() );

			//
			// there is a point, and it was not rolled
			//

			else if (m_diceTotal == 7)
				Loser(CrapsBet::Pass);

			// this bet will continue
			else
				Continue(CrapsBet::Pass);

		}

	}
}

void
CrapsGame::ProcessDontPassBets(int32 *continueBets, int32 *continueBonusBets)
{
	if (m_point == 0)
	{
		if (m_round->getBet(CrapsBet::DontPass)->getAmount() > 0)
		{
			if (m_diceTotal == 7 || m_diceTotal == 11)
				Loser(CrapsBet::DontPass);

			else if (m_diceTotal == 2 || m_diceTotal == 3)
				Winner(CrapsBet::DontPass, m_round->getBet(CrapsBet::DontPass)->getAmount() );

			// 12 is a push
			else if (m_diceTotal == 12)
				Push(CrapsBet::DontPass);

			else
			{
				if (m_current->getBet(CrapsBet::DontPass)->getAmount() == 0)
				{
					*m_current->getBet(CrapsBet::DontPass) = *m_round->getBet(CrapsBet::DontPass);
				}

				Continue(CrapsBet::DontPass);
			}
		}
		// clear any previous results still hanging around
		else
			Loser(CrapsBet::DontPass);
	}
	// if we've come here, then the bet exists in the 'current game' --
	// it must have previously been made,
	else
	{
		if (m_round->getBet(CrapsBet::DontPass)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(CrapsBet::DontPass)->getAmount();
			*continueBonusBets += m_current->getBet(CrapsBet::DontPass)->getBonusAmount();

			// clipinski case 4815
			// If the value of this bet has changed, we need to update the current round.
			m_current->getBet(CrapsBet::DontPass)->setAmount(m_round->getBet(CrapsBet::DontPass)->getAmount());
			m_current->getBet(CrapsBet::DontPass)->setBonusAmount(m_round->getBet(CrapsBet::DontPass)->getBonusAmount());

			// Don't Pass loser
			if (m_diceTotal == m_point)
				Loser(CrapsBet::DontPass);

			else if (m_diceTotal == 7)
				Winner(CrapsBet::DontPass, m_round->getBet(CrapsBet::DontPass)->getAmount() );

			else
				Continue(CrapsBet::DontPass);
		}
        else
        {
            // RPF 20100518 CSE-583
            if (m_diceTotal == 7 || m_diceTotal == m_point)
                Loser(CrapsBet::DontPass);
        }
	}
}

void
CrapsGame::ProcessPassOddsBets(int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(CrapsBet::PassOdds);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(CrapsBet::PassOdds)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(CrapsBet::PassOdds)->getAmount();
			*continueBonusBets += m_current->getBet(CrapsBet::PassOdds)->getBonusAmount();
		}

		if (m_diceTotal == 7)
			Loser(CrapsBet::PassOdds);

		else if (m_diceTotal == m_point)
			Winner(CrapsBet::PassOdds, TrueOdds(amount, m_point) );

		else
		{
			// if the bet exists in the 'current game' then it must have previously
			// been made, and this is a continuing bet
			*m_current->getBet(CrapsBet::PassOdds) = *bet;

			Continue(CrapsBet::PassOdds);
		}
	}
	// clear any previous results still hanging around
	else
		Loser(CrapsBet::PassOdds);

}


void
CrapsGame::ProcessDontPassOddsBets(int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(CrapsBet::DontPassOdds);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(CrapsBet::DontPassOdds)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(CrapsBet::DontPassOdds)->getAmount();
			*continueBonusBets += m_current->getBet(CrapsBet::DontPassOdds)->getBonusAmount();
		}

		if (m_diceTotal == 7)
			Winner(CrapsBet::DontPassOdds, DontTrueOdds(amount, m_point) );

		else if (m_diceTotal == m_point)
			Loser(CrapsBet::DontPassOdds);

		else
		{

			*m_current->getBet(CrapsBet::DontPassOdds) = *bet;

			Continue(CrapsBet::DontPassOdds);
		}
	}
	// clear any previous results still hanging around
	else
		Loser(CrapsBet::DontPassOdds);

}


void
CrapsGame::ProcessComeBets()
{
	if (m_round->getBet(CrapsBet::Come)->getAmount() > 0)
	{
		switch (m_diceTotal)
		{
		case 7:
		case 11:
			Winner(CrapsBet::Come, m_round->getBet(CrapsBet::Come)->getAmount());
			// Come bet is not allowed on next roll.
			break;

		case 2:
		case 3:
		case 12:
			Loser(CrapsBet::Come);
			break;

			// a come point is established...move the bet to the come #
		case 4:
			MoveComeTo(CrapsBet::Come4, 4);
			break;

		case 5:
			MoveComeTo(CrapsBet::Come5, 5);
			break;

		case 6:
			MoveComeTo(CrapsBet::Come6, 6);
			break;

		case 8:
			MoveComeTo(CrapsBet::Come8, 8);
			break;

		case 9:
			MoveComeTo(CrapsBet::Come9, 9);
			break;

		case 10:
			MoveComeTo(CrapsBet::Come10, 10);
			break;

		}
	}
	// clear any previous results still hanging around
	else
		Loser(CrapsBet::Come);

}

void
CrapsGame::ProcessDontComeBets()
{
	if (m_round->getBet(CrapsBet::DontCome)->getAmount() > 0)
	{
		switch (m_diceTotal)
		{
		case 7:
		case 11:
			Loser(CrapsBet::DontCome);
			break;

		case 2:
		case 3:
			Winner(CrapsBet::DontCome, m_round->getBet(CrapsBet::DontCome)->getAmount());
			break;

		case 12:
			Push(CrapsBet::DontCome);
			break;

			// a don't come point is established...move the bet to the don't come #
		case 4:
			MoveDontComeTo(CrapsBet::DontCome4, 4);
			break;

		case 5:
			MoveDontComeTo(CrapsBet::DontCome5, 5);
			break;

		case 6:
			MoveDontComeTo(CrapsBet::DontCome6, 6);
			break;

		case 8:
			MoveDontComeTo(CrapsBet::DontCome8, 8);
			break;

		case 9:
			MoveDontComeTo(CrapsBet::DontCome9, 9);
			break;

		case 10:
			MoveDontComeTo(CrapsBet::DontCome10, 10);
			break;

		}
	}
	// clear any previous results still hanging around
	else
		Loser(CrapsBet::DontCome);
}

void
CrapsGame::ProcessComeOddsBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessComeOddsBet(CrapsBet::Come4Odds, 4, continueBets, continueBonusBets);
	ProcessComeOddsBet(CrapsBet::Come5Odds, 5, continueBets, continueBonusBets);
	ProcessComeOddsBet(CrapsBet::Come6Odds, 6, continueBets, continueBonusBets);
	ProcessComeOddsBet(CrapsBet::Come8Odds, 8, continueBets, continueBonusBets);
	ProcessComeOddsBet(CrapsBet::Come9Odds, 9, continueBets, continueBonusBets);
	ProcessComeOddsBet(CrapsBet::Come10Odds, 10, continueBets, continueBonusBets);
}


void
CrapsGame::ProcessComeOddsBet(uint8 betID, int32 theNumber, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{

		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		if (m_diceTotal == 7)
		{
			// this bet is 'off' when the point is off,
			// it gets returned if the bet it depends on
			// (in this case, a Come Number bet) is removed (won or lost)
			if (m_point == 0)
				Push(betID);
			else
				Loser(betID);
		}
		else if (m_diceTotal == theNumber)
		{
			if (m_point == 0)
				Push(betID);
			else
				Winner(betID, TrueOdds(amount, m_diceTotal) );
		}
		else
		{
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}

	}
	// clear any previous results still hanging around
	else
		Loser(betID);
}

void
CrapsGame::ProcessDontComeOddsBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessDontComeOddsBet(CrapsBet::DontCome4Odds, 4, continueBets, continueBonusBets);
	ProcessDontComeOddsBet(CrapsBet::DontCome5Odds, 5, continueBets, continueBonusBets);
	ProcessDontComeOddsBet(CrapsBet::DontCome6Odds, 6, continueBets, continueBonusBets);
	ProcessDontComeOddsBet(CrapsBet::DontCome8Odds, 8, continueBets, continueBonusBets);
	ProcessDontComeOddsBet(CrapsBet::DontCome9Odds, 9, continueBets, continueBonusBets);
	ProcessDontComeOddsBet(CrapsBet::DontCome10Odds, 10, continueBets, continueBonusBets);
}


void
CrapsGame::ProcessDontComeOddsBet(uint8 betID, int32 theNumber, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		if (m_diceTotal == 7)
		{
			if (m_point == 0)
				Push(betID);
			else
				Winner(betID, DontTrueOdds(amount, theNumber) );
		}
		else if (m_diceTotal == theNumber)
		{
			if (m_point == 0)
				Push(betID);
			else
				Loser(betID);
		}
		else
		{
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}

	}
	else
		Loser(betID);

}

void
CrapsGame::ProcessComeNumberBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessComeNumberBet(CrapsBet::Come4, 4, continueBets, continueBonusBets);
	ProcessComeNumberBet(CrapsBet::Come5, 5, continueBets, continueBonusBets);
	ProcessComeNumberBet(CrapsBet::Come6, 6, continueBets, continueBonusBets);
	ProcessComeNumberBet(CrapsBet::Come8, 8, continueBets, continueBonusBets);
	ProcessComeNumberBet(CrapsBet::Come9, 9, continueBets, continueBonusBets);
	ProcessComeNumberBet(CrapsBet::Come10, 10, continueBets, continueBonusBets);
}

// these bets are never placed directly by the user,
// they are come bets that are moved
void
CrapsGame::ProcessComeNumberBet(uint8 betID, int32 theNumber, int32 *continueBets, int32 *continueBonusBets)
{
	// we use m_current, not m_round because when this is first
	// moved from the come, it is not marked as a come number bet
	// with a positive amount (the come bet had the positive amount)
	CrapsBet	*bet = m_current->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	// when the current is > 0 and the round is > 0, then
	// the bet has been previously carried, ie, it is continuing
	if ( (amount > 0) && (m_round->getBet(betID)->getAmount() > 0) )
	{

		*continueBets += m_current->getBet(betID)->getAmount();
		*continueBonusBets += m_current->getBet(betID)->getBonusAmount();

		if (m_diceTotal == 7)
			Loser(betID);

		else if (m_diceTotal == theNumber)
			Winner(betID, amount);

		else
			Continue(betID);

	}
	else if ( (amount == 0) && (m_round->getBet(betID)->getAmount() == 0) )
		Loser(betID);

	else {}
}


void
CrapsGame::ProcessDontComeNumberBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessDontComeNumberBet(CrapsBet::DontCome4, 4, continueBets, continueBonusBets);
	ProcessDontComeNumberBet(CrapsBet::DontCome5, 5, continueBets, continueBonusBets);
	ProcessDontComeNumberBet(CrapsBet::DontCome6, 6, continueBets, continueBonusBets);
	ProcessDontComeNumberBet(CrapsBet::DontCome8, 8, continueBets, continueBonusBets);
	ProcessDontComeNumberBet(CrapsBet::DontCome9, 9, continueBets, continueBonusBets);
	ProcessDontComeNumberBet(CrapsBet::DontCome10, 10, continueBets, continueBonusBets);
}


void
CrapsGame::ProcessDontComeNumberBet(uint8 betID, int32 theNumber, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_current->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if ( (amount > 0) && (m_round->getBet(betID)->getAmount() > 0) )
	{

		*continueBets += m_current->getBet(betID)->getAmount();
		*continueBonusBets += m_current->getBet(betID)->getBonusAmount();

		if (m_diceTotal == 7)
			Winner(betID, amount);

		else if (m_diceTotal == theNumber)
			Loser(betID);

		else
			Continue(betID);

	}
	else if ( (amount == 0) && (m_round->getBet(betID)->getAmount() == 0) )
		Loser(betID);

}

void
CrapsGame::ProcessBuyBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessBuyBet(CrapsBet::Buy4, continueBets, continueBonusBets);
	ProcessBuyBet(CrapsBet::Buy5, continueBets, continueBonusBets);
	ProcessBuyBet(CrapsBet::Buy6, continueBets, continueBonusBets);
	ProcessBuyBet(CrapsBet::Buy8, continueBets, continueBonusBets);
	ProcessBuyBet(CrapsBet::Buy9, continueBets, continueBonusBets);
	ProcessBuyBet(CrapsBet::Buy10, continueBets, continueBonusBets);
}

void
CrapsGame::ProcessBuyBet(uint8 betID, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		if (m_diceTotal == 7)
		{
			Loser(betID);
			return;
		}

		int32 howMuch, win;

		// the house takes a 5% commision off the top on this bet
		// house commission is built into the payout odds below...
		howMuch = amount;
		win = 0;
		switch (betID)
		{
		case CrapsBet::Buy4:
			if (m_diceTotal == 4)
				// True odds of 2:1
				win = (howMuch * 39) / 20;
			break;

		case CrapsBet::Buy5:
			if (m_diceTotal == 5)
				// True odds of 3:2
				win = (howMuch * 29) / 20;
			break;

		case CrapsBet::Buy6:
			// True odds of 6:5
			if (m_diceTotal == 6)
				win = (howMuch * 23) / 20;
			break;

		case CrapsBet::Buy8:
			// True odds of 6:5
			if (m_diceTotal == 8)
				win = (howMuch * 23) / 20;
			break;

		case CrapsBet::Buy9:
			// True odds of 3:2
			if (m_diceTotal == 9)
				win = (howMuch * 29) / 20;
			break;

		case CrapsBet::Buy10:
			// True odds of 2:1
			if (m_diceTotal == 10)
				win = (howMuch * 39) / 20;
			break;

		}

		if (win > 0)
			Winner(betID, win);

		else
		{
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}

	}
	else
		Loser(betID);
}

void
CrapsGame::ProcessPlaceBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessPlaceBet(CrapsBet::Place4, continueBets, continueBonusBets);
	ProcessPlaceBet(CrapsBet::Place5, continueBets, continueBonusBets);
	ProcessPlaceBet(CrapsBet::Place6, continueBets, continueBonusBets);
	ProcessPlaceBet(CrapsBet::Place8, continueBets, continueBonusBets);
	ProcessPlaceBet(CrapsBet::Place9, continueBets, continueBonusBets);
	ProcessPlaceBet(CrapsBet::Place10, continueBets, continueBonusBets);
}

void
CrapsGame::ProcessPlaceBet(uint8 betID, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;
	bool8		 cont = false;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		if (m_diceTotal == 7)
		{
			Loser(betID);
			return;
		}

		switch (betID)
		{
		case CrapsBet::Place4:

			if (m_diceTotal == 4)
				Winner(betID, amount * 9 / 5);
			else
				cont = true;

			break;

		case CrapsBet::Place5:

			if (m_diceTotal == 5)
				Winner(betID, amount * 7 / 5);
			else
				cont = true;

			break;

		case CrapsBet::Place6:

			if (m_diceTotal == 6)
				Winner(betID, amount * 7 / 6);
			else
				cont = true;

			break;

		case CrapsBet::Place8:

			if (m_diceTotal == 8)
				Winner(betID, amount * 7 / 6);
			else
				cont = true;

			break;

		case CrapsBet::Place9:

			if (m_diceTotal == 9)
				Winner(betID, amount * 7 / 5);
			else
				cont = true;

			break;

		case CrapsBet::Place10:

			if (m_diceTotal == 10)
				Winner(betID, amount * 9 / 5);
			else
				cont = true;

			break;

		}

		if (cont)
		{
			// if the bet exists in the 'current game' then it must have previously
			// been made, and this is a continuing bet

			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}
	}
	else
		Loser(betID);

}

void
CrapsGame::ProcessLayBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessLayBet(CrapsBet::Lay4, continueBets, continueBonusBets);
	ProcessLayBet(CrapsBet::Lay5, continueBets, continueBonusBets);
	ProcessLayBet(CrapsBet::Lay6, continueBets, continueBonusBets);
	ProcessLayBet(CrapsBet::Lay8, continueBets, continueBonusBets);
	ProcessLayBet(CrapsBet::Lay9, continueBets, continueBonusBets);
	ProcessLayBet(CrapsBet::Lay10, continueBets, continueBonusBets);
}


void
CrapsGame::ProcessLayBet(uint8 betID, int32 *continueBets, int32 *continueBonusBets)
{
	// Player wins true odds if 7 comes before number,
	// but house takes 4% commision first

	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;
	bool8		 cont = false;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		switch (betID)
		{
		case CrapsBet::Lay4:

			if (m_diceTotal == 4)
				Loser(betID);
			else if (m_diceTotal == 7)
				// Now pay true odds of 1 to 2 minus 5% commission ON THE POTENTIAL WINNINGS
				Winner(betID, (amount * 20) / 41);
			else
				cont = true;

			break;

		case CrapsBet::Lay5:

			if (m_diceTotal == 5)
				Loser(betID);
			else if (m_diceTotal == 7)
				// Now pay true odds of 2 to 3 minus 5% commission ON THE POTENTIAL WINNINGS
				Winner(betID, (amount * 20) / 31);
			else
				cont = true;

			break;

		case CrapsBet::Lay6:

			if (m_diceTotal == 6)
				Loser(betID);
			else if (m_diceTotal == 7)
				// Now pay true odds of 5 to 6 minus 5% commission ON THE POTENTIAL WINNINGS
				Winner(betID, (amount * 20) / 25);
			else
				cont = true;

			break;

		case CrapsBet::Lay8:

			if (m_diceTotal == 8)
				Loser(betID);
			else if (m_diceTotal == 7)
				// Now pay true odds of 5 to 6 minus 5% commission ON THE POTENTIAL WINNINGS
				Winner(betID, (amount * 20) / 25);
			else
				cont = true;

			break;

		case CrapsBet::Lay9:

			if (m_diceTotal == 9)
				Loser(betID);
			else if (m_diceTotal == 7)
				// Now pay true odds of 2 to 3 minus 5% commission ON THE POTENTIAL WINNINGS
				Winner(betID, (amount * 20) / 31);
			else
				cont = true;

			break;

		case CrapsBet::Lay10:

			if (m_diceTotal == 10)
				Loser(betID);
			else if (m_diceTotal == 7)
				// Now pay true odds of 1 to 2 minus 5% commission ON THE POTENTIAL WINNINGS
				Winner(betID, (amount * 20) / 41);
			else
				cont = true;

			break;

		}

		if (cont)
		{
			// if the bet exists in the 'current game' then it must have previously
			// been made, and this is a continuing bet
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}
	}
	else
		Loser(betID);

}

void
CrapsGame::ProcessPlaceLoseBets(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessPlaceLoseBet(CrapsBet::Place4Lose, continueBets, continueBonusBets);
	ProcessPlaceLoseBet(CrapsBet::Place5Lose, continueBets, continueBonusBets);
	ProcessPlaceLoseBet(CrapsBet::Place6Lose, continueBets, continueBonusBets);
	ProcessPlaceLoseBet(CrapsBet::Place8Lose, continueBets, continueBonusBets);
	ProcessPlaceLoseBet(CrapsBet::Place9Lose, continueBets, continueBonusBets);
	ProcessPlaceLoseBet(CrapsBet::Place10Lose, continueBets, continueBonusBets);
}

void
CrapsGame::ProcessPlaceLoseBet(uint8 betID, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;
	bool8		 cont = false;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		switch (betID)
		{
		case CrapsBet::Place4Lose:

			if (m_diceTotal == 4)
				Loser(betID);
			else if (m_diceTotal == 7)
				// To use these odds, the client must make the bet in multiple of $11
				Winner(betID, amount * 5 / 11);

			else
				cont = true;

			break;

		case CrapsBet::Place5Lose:

			if (m_diceTotal == 5)
				Loser(betID);
			else if (m_diceTotal == 7)
				// To use these odds, the client must make the bet in multiple of $8
				Winner(betID, amount * 5 / 8);
			else
				cont = true;

			break;

		case CrapsBet::Place6Lose:

			if (m_diceTotal == 6)
				Loser(betID);
			else if (m_diceTotal == 7)
				// To use these odds, the client must make the bet in multiple of $5
				Winner(betID, amount * 4 / 5);
			else
				cont = true;

			break;

		case CrapsBet::Place8Lose:

			if (m_diceTotal == 8)
				Loser(betID);
			else if (m_diceTotal == 7)
				// To use these odds, the client must make the bet in multiple of $5
				Winner(betID, amount * 4 / 5);
			else
				cont = true;

			break;

		case CrapsBet::Place9Lose:

			if (m_diceTotal == 9)
				Loser(betID);
			else if (m_diceTotal == 7)
				// To use these odds, the client must make the bet in multiple of $8
				Winner(betID, amount * 5 / 8);
			else
				cont = true;

			break;

		case CrapsBet::Place10Lose:

			if (m_diceTotal == 10)
				Loser(betID);
			else if (m_diceTotal == 7)
				// To use these odds, the client must make the bet in multiple of $11
				Winner(betID, amount * 5 / 11);

			else
				cont = true;

			break;

		}
		if (cont)
		{
			// if the bet exists in the 'current game' then it must have previously
			// been made, and this is a continuing bet
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}
	}
	else
		Loser(betID);

}

void
CrapsGame::ProcessBigBets(uint8 betID, int32 theNumber, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		if (m_diceTotal == 7)
			Loser(betID);

		else if (m_diceTotal == theNumber)
			Winner(betID, amount);

		else
		{
			// if the bet exists in the 'current game' then it must have previously
			// been made, and this is a continuing bet
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}

	}
	else
		Loser(betID);

}


void
CrapsGame::ProcessFieldBet()
{
	CrapsBet	*bet = m_round->getBet(CrapsBet::Field);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		switch (m_diceTotal)
		{
		case 3:
		case 4:
		case 9:
		case 10:
		case 11:
			Winner(CrapsBet::Field, amount);
			break;

		case 2:
			Winner(CrapsBet::Field, 2 * amount);
			break;

		case 12:
			Winner(CrapsBet::Field, m_tableLimits->m_field12Odds * amount);
			break;

		case 5:
		case 6:
		case 7:
		case 8:
			Loser(CrapsBet::Field);
			break;
		}
	}
	// clear any prev winnings if they are hanging around
	else
		Loser(CrapsBet::Field);
}


void
CrapsGame::ProcessHardWays(int32 *continueBets, int32 *continueBonusBets)
{
	ProcessHardWay(CrapsBet::Hard4, continueBets, continueBonusBets);
	ProcessHardWay(CrapsBet::Hard6, continueBets, continueBonusBets);
	ProcessHardWay(CrapsBet::Hard8, continueBets, continueBonusBets);
	ProcessHardWay(CrapsBet::Hard10, continueBets, continueBonusBets);
}

void
CrapsGame::ProcessHardWay(uint8 betID, int32 *continueBets, int32 *continueBonusBets)
{
	CrapsBet	*bet		 = m_round->getBet(betID);
	int32		 amount		 = 0;

	if (bet)
		amount = bet->getAmount();

	if (amount > 0)
	{
		if (m_current->getBet(betID)->getAmount() > 0)
		{
			*continueBets += m_current->getBet(betID)->getAmount();
			*continueBonusBets += m_current->getBet(betID)->getBonusAmount();
		}

		// this bet is 'off' when the point is off
		//		if (m_point == 0)
		//		{
		//			*m_current->getBet(betID) = *bet;
		//
		//			Continue(betID);
		//		}
		//		else
		//		{

		bool8 theHardWay = (bool8)(m_die1 == m_die2);
		int32 theNumber = 0;

		// pay odds if a double is rolled before 7, or non-double total
		switch (betID)
		{
		case CrapsBet::Hard4:
			theNumber = 4;
			break;

		case CrapsBet::Hard6:
			theNumber = 6;
			break;

		case CrapsBet::Hard8:
			theNumber = 8;
			break;

		case CrapsBet::Hard10:
			theNumber = 10;
			break;
		}

		if (m_diceTotal == 7)
			Loser(betID);

		else if (m_diceTotal == theNumber)
		{
			if (!theHardWay)
				Loser(betID);	// hard way is down
			else
			{
				if (amount > 0)
				{
					// we have a winner:
					//	 Hard 6 or 8 pays 9X
					//	 Hard 4 or 10 pays 7X
					int32 mult = (theNumber == 6 || theNumber == 8) ? 9 : 7;

					Winner(betID, mult * amount);
				}
				// clear any prev winnings if they are hanging around
				else
					Loser(betID);
			}
		}
		else
		{
			// if the bet exists in the 'current game' then it must have previously
			// been made, and this is a continuing bet
			*m_current->getBet(betID) = *bet;

			Continue(betID);
		}
		//		} // endif if (m_point == 0)
	}
	else
		Loser(betID);
}

void
CrapsGame::ProcessOneShotBets()
{

	if (m_diceTotal == 7)
		if (m_round->getBet(CrapsBet::Seven)->getAmount() > 0)
			Winner(CrapsBet::Seven, 4 * m_round->getBet(CrapsBet::Seven)->getAmount() );
	// clear any prev winnings if they are hanging around
		else
			Loser(CrapsBet::Seven);
	else
		Loser(CrapsBet::Seven);


	if (m_diceTotal == 3)
		if (m_round->getBet(CrapsBet::Craps3)->getAmount() > 0)
			Winner(CrapsBet::Craps3, 15 * m_round->getBet(CrapsBet::Craps3)->getAmount() );
	// clear any prev winnings if they are hanging around
		else
			Loser(CrapsBet::Craps3);
	else
		Loser(CrapsBet::Craps3);


	if (m_diceTotal == 2)
		if (m_round->getBet(CrapsBet::SnakeEyes)->getAmount() > 0)
			Winner(CrapsBet::SnakeEyes, 30 * m_round->getBet(CrapsBet::SnakeEyes)->getAmount() );
	// clear any prev winnings if they are hanging around
		else
			Loser(CrapsBet::SnakeEyes);
	else
		Loser(CrapsBet::SnakeEyes);


	if (m_diceTotal == 11)
	{
		if (m_round->getBet(CrapsBet::Eleven)->getAmount() > 0)
			Winner(CrapsBet::Eleven, 15 * m_round->getBet(CrapsBet::Eleven)->getAmount() );
		// clear any prev winnings if they are hanging around
		else
			Loser(CrapsBet::Eleven);

		if (m_round->getBet(CrapsBet::YoEleven)->getAmount() > 0)
			Winner(CrapsBet::YoEleven, 15 * m_round->getBet(CrapsBet::YoEleven)->getAmount() );
		// clear any prev winnings if they are hanging around
		else
			Loser(CrapsBet::YoEleven);
	}
	else
	{
		Loser(CrapsBet::Eleven);
		Loser(CrapsBet::YoEleven);
	}


	if (m_diceTotal == 12)
		if (m_round->getBet(CrapsBet::BoxCars)->getAmount() > 0)
			Winner(CrapsBet::BoxCars, 30 * m_round->getBet(CrapsBet::BoxCars)->getAmount() );
	// clear any prev winnings if they are hanging around
		else
			Loser(CrapsBet::BoxCars);
	else
		Loser(CrapsBet::BoxCars);

}

void
CrapsGame::ProcessAnyCrapsBets()
{
	ProcessAnyCraps(CrapsBet::AnyCraps);
	ProcessAnyCraps(CrapsBet::CircleAnyCraps);
}

void
CrapsGame::ProcessAnyCraps(uint8 betID)
{
	CrapsBet	*bet = m_round->getBet(betID);
	int32		 amount = 0;

	if (bet)
		amount = bet->getAmount();

	if (m_diceTotal == 2 || m_diceTotal == 3 || m_diceTotal == 12)
		if (amount > 0)
			Winner(betID, 7 * amount);
	// clear any prev winnings if they are hanging around
		else
			Loser(betID);
	else
		Loser(betID);
}


int32
CrapsGame::TrueOdds(int32 betAmount, int32 theNumber)
{
	switch (theNumber)
	{
	case 6:
	case 8:
		return (6 * betAmount) / 5;

	case 5:
	case 9:
		return (3 * betAmount) / 2;

	case 4:
	case 10:
		return 2 * betAmount;

	default:
		return 0;
	}
}


int32 CrapsGame::DontTrueOdds(int32 betAmount, int32 theNumber)
{
	switch (theNumber)
	{
	case 6:
	case 8:
		return (5 * betAmount) / 6;

	case 5:
	case 9:
		return (2 * betAmount) / 3;

	case 4:
	case 10:
		return betAmount / 2;

	default:
		return 0;
	}
}

// kharmon.  06-19-06.  #3077.  Sic Bo implementation.
// The game objects now handle all game specific messages.  So, this method is called from the
// connection whenever a message comes through that the connection object doesn't recognize.
bool8 CrapsGame::handleMessage(unsigned char *msgbuf, int32 len)
{
	bool8 bRetVal = true;

	switch (msgbuf[0])
	{
	case 'R':
		{
			int32 i = 0;
			uint8 numBets = 0;
			uint8 betID = 0;
			int32 used = 0;
			int32 amount = 0;
			bool8 abort = 0;
			int32 *bets = (int32*)0;
			CrapsRound *round = (CrapsRound*)0;
			CrapsRound *current = (CrapsRound*)0;

			used = 1;
			used += m_conn->msgRemove(msgbuf + used, &numBets);

			if (numBets < 0 || numBets != CrapsBet::NUMBETS)
			{
				Log::msgWarning("Craps Roll: invalid number of bets  ");

				m_conn->trackaddBadPacket(INVALID_NUMBER_BETS,msgbuf[0],(char*)msgbuf,len);

				m_conn->msgStart();
				m_conn->msgAdd((uint8)'B');
				m_conn->msgEnd();

				break;
			}
			else
			{
				bets = new int32[numBets];
				memset(bets, 0, numBets*sizeof(int32));
			}

			int32 totalBet			= 0;
			int32 grandfatheredBets	= 0;
			int32 newbets = 0;
			int32 newBetsThisGame = 0;
			int32 newBetBonusBalanceCounter = 0;

			for (i = 0; i < numBets; i++)
			{
				used += m_conn->msgRemove(msgbuf + used, &amount);
				used += m_conn->msgRemove(msgbuf + used, &betID);

				// Fogbugz 19771 -- Possible exploit in craps if a (hacked) client sends 
				// negative bet amounts.
				//
				// The problem with negative bets is that they are not written to the database,
				// but the total bet gets reduced. This could lead to a situation where the
				// total bet in crapsgames is not the sum of the individual bets in crapsbets.
				if ( amount < 0 )
				{
					// Log the invalid negative bet
					try
					{
						String pid;
						CrapsConnection::Info *info = m_conn->getCasinoSpecificInfo();
						if ( info )
						{
							pid = info->pid;
						}

						Log::msgError("Craps Roll: negative bet amount"
							" PID: %S Bet ID: %d, amount: %ld", (const uint16*) pid, betID, amount);
					}
					catch(...)
					{
						// We don't really care about any errors/exceptions while logging,
						// so go ahead and ignore this for now. This code was added as a
						// hot-fix which is why we are taking the extra precaution of try/catch.
					}

					// These negative bets should probably be rejected by ValidateBets, but
					// since that function currently allows negative bets I've added this 
					// code to just treat them as "non-bets" for now since that is a smaller
					// change.
					amount = 0;
				}

				// Check that betID is a valid ID
				if ((betID >= 0) && (betID < CrapsBet::NUMBETS))
				{	
					// newBetsThisGame tracks if a bet amount has increased since the last round
					if (amount > getCurrent()->getBet(betID)->getAmount()) 
						newBetsThisGame += amount-bets[betID];

					bets[betID] = amount;
					totalBet += amount;

					if (getCurrent()->getBet((uint8)i)->isGrandfathered() )
						grandfatheredBets += amount;
				}
			}

			int32 balance, compBalance, bonusBalance;

			m_conn->getGameDBInterface()->trackGetBalance(&balance,&compBalance, &bonusBalance);

			// This represents just non-grandfathered bets
			//  A grandfathered bet is one that was created in a previous session and was restored from a saved game
			newbets = totalBet - grandfatheredBets;

			if (newBetsThisGame > 0)
			{
				if (bonusBalance >= newBetsThisGame)
					newBetBonusBalanceCounter =  newBetsThisGame;
				else
					newBetBonusBalanceCounter =  bonusBalance;
			}

			CTableLimits *tableLimits = ((CrapsSQL *) m_conn->getGameDBInterface())->getTableLimits();

			// since previously made bets that are continuing have already
			// been subtracted from the balance, check that there is enough money
			// to place only the new bets
			if (balance < totalBet - getCurrent()->totalBet() )	// not enough money
			{
				Log::msgWarning("Craps Roll: out of money ");

				m_conn->msgStart();
				m_conn->msgAdd((uint8)'$');
				m_conn->msgEnd();
			}
			else if ( (balance >= 0) && ((newbets > 0 &&
				(newbets >= tableLimits->m_minTable) &&
				(newbets <= tableLimits->m_maxTable)) ||
				(grandfatheredBets > 0)))
			{

				round = getRound();
				current = getCurrent();
				abort = (bool8)(round == (CrapsRound*)0);

				for (i = 0; !abort && i < numBets; i++)
				{
					if (round->getBet((uint8)i) == (CrapsBet *)0)
					{
						abort = true;
						Log::msgError("Craps Roll: failed to create bet"
							" ID: %d, amount: %ld", i, bets[i]);
					}
					else
					{
						int32 prevBetAmount = current->getBet((uint8)i)->getAmount();
						int32 prevBonusBetAmount = current->getBet((uint8)i)->getBonusAmount();
						int32 newBetDiff = bets[i] - prevBetAmount;

						round->getBet((uint8)i)->setAmount(bets[i]);
						round->getBet((uint8)i)->setBonusAmount(prevBonusBetAmount);

						/**********************************************************
						CHECK FOR ALLOTMENT OF BONUS BALANCE
						***********************************************************/

						// Only check for bonus bet adjustment if the bet amount itself has changed
						if (newBetDiff > 0)
						{
							// Balance of the bet has increased -- we only care if there is bonus money to apply to it
							if (newBetBonusBalanceCounter > 0)
							{
								// This bet will have at least some new bonus money applied to it
								if (newBetBonusBalanceCounter < newBetDiff)
								{
									// Partial bonus balance to the bet
									round->getBet((uint8)i)->setBonusAmount(prevBonusBetAmount + newBetBonusBalanceCounter);
									newBetBonusBalanceCounter = 0;
								}
								else
								{
									// Full bonus balance to the bet
									round->getBet((uint8)i)->setBonusAmount(prevBonusBetAmount + newBetDiff);
									newBetBonusBalanceCounter -= newBetDiff;
								}
							}
						}
						else if (newBetDiff < 0)
						{
							// Balance of the bet has decreased -- we only care if there is bonus balance currently applied to the bet
							if (prevBonusBetAmount >  0)
							{
								if (-newBetDiff >= prevBonusBetAmount)
								{
									// Zero out the bonus balance for this bet
									round->getBet((uint8)i)->setBonusAmount(0);
								}
								else
								{
									// Decrease by the amount decreased from the bet
									round->getBet((uint8)i)->setBonusAmount(prevBonusBetAmount + newBetDiff);
								}
							}
						}
					}
				}

				if (!abort)
				{

					// validate the bets
					int32 valid = validateBets(round);

					// if valid is not less than 0, then
					// valid == the id of the invalid bet
					if (valid >= 0)
					{
						Log::msgError("Craps Roll: invalid bet ID: %d,"
							" amount: %ld", valid,
							round->getBet((uint8)valid)->getAmount() );

						m_conn->msgStart();
						m_conn->msgAdd((uint8)'B');
						m_conn->msgEnd();
					}
					// otherwise, all bets were valid
					else
					{

						// this takes care of processing the bets
						if ( !(roll(round, &balance, &compBalance, &bonusBalance)) )
						{
							Log::msgError("Craps Roll: CrapsGame::roll()"
								" trackRoll() sql error ");

							m_conn->msgStart();
							m_conn->msgAdd((uint8)'N');
							m_conn->msgEnd();
						}

					}
				}
				else
				{
					if (!round)
						Log::msgError("Craps Round: failed to create"
						" Round");

					m_conn->msgStart();
					m_conn->msgAdd((uint8)'N');
					m_conn->msgEnd();
				}

			}
			else if (balance > 0)	// bad bet -- total bet or number of bets was <= 0
			{
				Log::msgWarning("Craps Roll:  invalid bet -- total bet or"
					" number of bets was <= 0 ");

				m_conn->msgStart();
				m_conn->msgAdd((uint8)'B');
				m_conn->msgEnd();
			}
			else {}

			if (bets)
			{
				delete [] bets;
				bets = (int32 *)0;
			}

			break;
		}


	default:
		{
			bRetVal = false;
			break;
		}
	}

	return bRetVal;
}

